import React, { useState, memo ,useMemo} from 'react';
// 1. 基础父组件状态变更
// const Child = () => {
//   console.log('子组件被渲染了');
//   return <div>我是子组件</div>;
// };

// const Parent = () => {
//   const [count, setCount] = useState(0);
//   console.log('父组件被渲染了');

//   return (
//     <div>
//       <h2>父组件</h2>
//       <p>Count: {count}</p>
//       <button onClick={() => setCount(count + 1)}>增加 Count</button>
//       <Child />
//     </div>
//   );
// };


// 2. 即使我们给子组件传递一个 prop，但只要父组件渲染，子组件依然会渲染。
// const Child = ({ name }) => {
//   console.log('子组件被渲染了');
//   return <div>你好, {name}</div>;
// };

// const Parent = () => {
//   const [count, setCount] = useState(0);
//   console.log('父组件被渲染了');

//   return (
//     <div>
//       <p>Count: {count}</p>
//       <button onClick={() => setCount(count + 1)}>增加 Count</button>
//       {/* "React" 这个字符串从未改变 */}
//       <Child name="React" />
//     </div>
//   );
// };

// 3. 传递引用类型Prop（对象）

// const Child = ({ user }) => {
//   console.log('子组件被渲染了 - user.name:', user.name);
//   return <div>用户名: {user.name}</div>;
// };

// const Parent = () => {
//   const [count, setCount] = useState(0);
//   console.log('父组件被渲染了');
  
//   // 每次渲染都会创建一个新的 user 对象
//   const user = { name: 'Alice' };

//   return (
//     <div>
//       <p>Count: {count}</p>
//       <button onClick={() => setCount(count + 1)}>增加 Count</button>
//       <Child user={user} />
//     </div>
//   );
// };


// 4. 传递引用类型Prop（函数）

// const Child = ({ onButtonClick }) => {
//   console.log('子组件被渲染了');
//   return <button onClick={onButtonClick}>点击我</button>;
// };

// const Parent = () => {
//   const [count, setCount] = useState(0);
//   console.log('父组件被渲染了');

//   // 每次渲染都会创建一个新的 handleClick 函数
//   const handleClick = () => {
//     console.log('按钮被点击了!');
//   };

//   return (
//     <div>
//       <p>Count: {count}</p>
//       <button onClick={() => setCount(count + 1)}>增加 Count</button>
//       <Child onButtonClick={handleClick} />
//     </div>
//   );
// };


// 1.解决方法使用 React.memo 包裹子组件
// const Child = memo(({ name }) => {
//   console.log('子组件被渲染了');
//   return <div>你好, {name}</div>;
// });

// const Parent = () => {
//   const [count, setCount] = useState(0);
//   console.log('父组件被渲染了');

//   return (
//     <div>
//       <p>Count: {count}</p>
//       <button onClick={() => setCount(count + 1)}>增加 Count</button>
//       <Child name="React" />
//     </div>
//   );
// };

// 2. React.memo 对引用类型失效
// const MemoizedChild = memo(({ user }) => {
//   console.log('子组件被渲染了 - user.name:', user.name);
//   return <div>用户名: {user.name}</div>;
// });

// const Parent = () => {
//   const [count, setCount] = useState(0);
//   console.log('父组件被渲染了');
  
//   const user = { name: 'Alice' }; // 依然是新对象

//   return (
//     <div>
//       <p>Count: {count}</p>
//       <button onClick={() => setCount(count + 1)}>增加 Count</button>
//       <MemoizedChild user={user} />
//     </div>
//   );
// };

// 3.useMemo - 缓存引用类型值



const MemoizedChild = memo(({ user }) => {
  console.log('子组件被渲染了 - user.name:', user.name);
  return <div>用户名: {user.name}</div>;
});

const Parent = () => {
  const [count, setCount] = useState(0);
  const [userName, setUserName] = useState('Alice');
  console.log('父组件被渲染了');

  // 使用 useMemo 缓存 user 对象
  // 只有当 userName 改变时，才会创建新的 user 对象
  const user = useMemo(() => ({ name: userName }), [userName]);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>增加 Count (子组件不渲染)</button>
      <button onClick={() => setUserName('Bob')}>改变 Name (子组件渲染)</button>
      <MemoizedChild user={user} />
    </div>
  );
};


export default Parent;